//
//  SignCardView.swift
//  Kosspot
//
//  Created by 胡辉 on 2025/8/3.
//

import SwiftUI
import Charts

struct SignCardView<Content: View>: View {
    let type: SignType
    let date: String
    let value: String
    let content: Content
    
    init(type: SignType, date: String, value: String, @ViewBuilder content: () -> Content) {
        self.type = type
        self.date = date
        self.value = value
        self.content = content()
    }
    
    var body: some View {
        ZStack {
            Color(hex: "#1A1A1A")
                .cornerRadius(16, corners: .allCorners)
            VStack(alignment: .leading, spacing: 0) {
                HStack(spacing: 0) {
                    Image(type.icon)
                        .resizable()
                        .scaledToFit()
                        .frame(width: 18, height: 18)
                    Text(type.name)
                        .font(.system(size: 16, weight: .medium))
                        .foregroundColor(.white)
                        .padding(.leading, 6)
                    Spacer()
                }
                Text(date)
                    .font(.system(size: 12, weight: .regular))
                    .foregroundColor(Color(hex: "#B2B2B2"))
                    .padding(.top, 7)
                Text(value)
                    .font(.system(size: 16, weight: .bold))
                    .foregroundColor(.white)
                    .padding(.top, 4)
                
                Spacer()
                content
                    .padding(.top, 5)
            }
            .padding(.horizontal, 12)
            .padding(.vertical, 16)
        }
        .frame(height: 184)
    }
}

struct HourSPO2: Identifiable {
    let id = UUID()
    let hour: Int
    let value: Int
}

// 血氧饱和度卡片示例
struct Spo2CardView: View {
    let date: String
    let value: String
    var samples: [HourSPO2] = [
        HourSPO2(hour: 0, value: 95),
        HourSPO2(hour: 1, value: 96),
        HourSPO2(hour: 2, value: 94),
        HourSPO2(hour: 3, value: 93),
        HourSPO2(hour: 4, value: 92),
        HourSPO2(hour: 5, value: 91),
        HourSPO2(hour: 6, value: 90),
        HourSPO2(hour: 7, value: 89),
        HourSPO2(hour: 8, value: 88),
        HourSPO2(hour: 9, value: 87),
        HourSPO2(hour: 10, value: 86),
        HourSPO2(hour: 11, value: 85),
        HourSPO2(hour: 12, value: 84),
        HourSPO2(hour: 13, value: 83),
        HourSPO2(hour: 14, value: 82),
        HourSPO2(hour: 15, value: 81),
        HourSPO2(hour: 16, value: 80),
        HourSPO2(hour: 17, value: 79),
        HourSPO2(hour: 18, value: 78),
        HourSPO2(hour: 19, value: 77),
        HourSPO2(hour: 20, value: 76),
        HourSPO2(hour: 21, value: 75),
        HourSPO2(hour: 22, value: 74),
        HourSPO2(hour: 23, value: 73)
    ]
    var body: some View {
        SignCardView(type: .spo2, date: date, value: value) {
            VStack(spacing: 8) {
                Chart(samples) { item in
                    PointMark(
                        x: .value("Hour", item.hour),
                        y: .value("SPO2", item.value)
                    )
                    .symbol(.circle)
                    .symbolSize(16)
                    .foregroundStyle(Color(hex: "#A75E60"))
                }
                .frame(height: 40)
                .chartYScale(domain: 70...100)
                .chartYAxis(.hidden)
                .chartXAxis {
                    AxisMarks(values: .stride(by: 1)) { value in
                        AxisGridLine(
                            stroke: StrokeStyle(
                                lineWidth: 0.5
                            )
                        )
                        .foregroundStyle(Color(hex: "#F5F5F5").opacity(0.3))
                    }
                }
                HStack {
                    Text("00:00")
                        .font(.system(size: 12))
                        .foregroundColor(Color(hex: "#B2B2B2"))
                    Spacer()
                    Text("24:00")
                        .font(.system(size: 12))
                        .foregroundColor(Color(hex: "#B2B2B2"))
                }
            }
        }
    }
}

// 睡眠卡片示例
struct SleepCardView: View {
    let quality: String
    let date: String
    
    var body: some View {
        SignCardView(type: .sleep, date: date, value: quality) {
            
            let cfg = ProgressConfig(
                segments: [
                    .init(color: Color(hex: "#E2DCFE"),  title: "有待提高",      alignment: .leading),
                    .init(color: Color(hex: "#C0B9FC"),   title: "",    alignment: .center),
                    .init(color: Color(hex: "#A498FC"), title: "",  alignment: .center),
                    .init(color: Color(hex: "#8775FF"),    title: "优", alignment: .trailing)
                ],
                gap: 2,
                barHeight: 10
            )
            
            SleepProgressBar(progress: 0.23, config: cfg)
            
//            SegmentedProgressBar(segments: [
//                (value: 25, color: Color(hex: "#E2DCFE")),
//                (value: 25, color: Color(hex: "#AC8FFF")),
//                (value: 25, color: Color(hex: "#8170FF")),
//                (value: 25, color: Color(hex: "#6129FF"))
//            ], currentValue: 23, showWord: ["有待提高","","","优"])
                
        }
    }
}

struct MonthWeight: Identifiable {
    let id = UUID()
    let day: Date
    let value: Double
}

// 体重卡片示例
struct WeightCardView: View {
    let value: String
    let date: String
    
    func generateMonthWeightData() -> [MonthWeight] {
        var samples: [MonthWeight] = []
        
        let today = Date()
        let calendar = Calendar.current
        
        guard let firstDayOfMonth = calendar.date(from: calendar.dateComponents([.year, .month], from: today)) else {
            return samples
        }
        
        guard let lastDayOfMonth = calendar.date(byAdding: DateComponents(month: 1, day: -1), to: firstDayOfMonth) else {
            return samples
        }
        
        let baseWeight = 68.0
        let randomRange = -2.0...2.0
        
        var currentDate = firstDayOfMonth
        while currentDate <= lastDayOfMonth {
            
            let randomWeight = baseWeight + Double.random(in: randomRange)
            
            let formattedWeight = Double(round(10 * randomWeight) / 10)
            
            samples.append(MonthWeight(day: currentDate, value: formattedWeight))
            
            guard let nextDate = calendar.date(byAdding: .day, value: 1, to: currentDate) else {
                break
            }
            currentDate = nextDate
        }
        
        return samples
    }
    
    var samples: [MonthWeight] {
        generateMonthWeightData()
    }
    
    private var firstDayOfMonth: String {
            let calendar = Calendar.current
            let today = Date()
            guard let firstDay = calendar.date(from: calendar.dateComponents([.year, .month], from: today)) else {
                return ""
            }
            let formatter = DateFormatter()
            formatter.dateFormat = "d/M"
            return formatter.string(from: firstDay)
        }
        
        private var lastDayOfMonth: String {
            let calendar = Calendar.current
            let today = Date()
            guard let firstDay = calendar.date(from: calendar.dateComponents([.year, .month], from: today)) else {
                return ""
            }
            guard let lastDay = calendar.date(byAdding: DateComponents(month: 1, day: -1), to: firstDay) else {
                return ""
            }
            let formatter = DateFormatter()
            formatter.dateFormat = "d/M"
            return formatter.string(from: lastDay)
        }
    
    private var areaGradient: LinearGradient {
            LinearGradient(
                gradient: Gradient(colors: [
                    Color(hex: "#6BCD79").opacity(0.9),
                    Color(hex: "#6BCD79").opacity(0.6),
                    Color(hex: "#6BCD79").opacity(0.0)
                ]),
                startPoint: .top,
                endPoint: .bottom
            )
        }
    
    var body: some View {
            SignCardView(type: .weight, date: date, value: value) {
                VStack(spacing: 8) {
                    Chart(samples) { item in
                        LineMark(
                            x: .value("日期", item.day, unit: .day),
                            y: .value("体重(kg)", item.value)
                        )
                        .foregroundStyle(Color(hex: "#6BCD79"))
                        AreaMark(
                            x: .value("日期", item.day, unit: .day),
                            y: .value("体重(kg)", item.value)
                        )
                        .foregroundStyle(areaGradient)
                        
                        
                    }
                    .frame(height: 40)
//                    .chartYScale(domain: 60...75)
                    .chartXAxis(.hidden)
                    .chartYAxis(.hidden)
                    HStack {
                        Text(firstDayOfMonth)
                            .font(.system(size: 12))
                            .foregroundColor(Color(hex: "#B2B2B2"))
                        Spacer()
                        Text(lastDayOfMonth)
                            .font(.system(size: 12))
                            .foregroundColor(Color(hex: "#B2B2B2"))
                    }
                }
            }
        }
}

// 压力卡片示例
struct PressureCardView: View {
    let value: String
    let level: String
    let date: String
    
    var samples: [HourSPO2] = [
        HourSPO2(hour: 0, value: 95),
        HourSPO2(hour: 1, value: 80),
        HourSPO2(hour: 2, value: 94),
        HourSPO2(hour: 3, value: 77),
        HourSPO2(hour: 4, value: 92),
        HourSPO2(hour: 5, value: 91),
        HourSPO2(hour: 6, value: 86),
        HourSPO2(hour: 7, value: 89),
        HourSPO2(hour: 8, value: 88),
        HourSPO2(hour: 9, value: 87),
        HourSPO2(hour: 10, value: 86),
        HourSPO2(hour: 11, value: 96),
        HourSPO2(hour: 12, value: 84),
        HourSPO2(hour: 13, value: 75),
        HourSPO2(hour: 14, value: 82),
        HourSPO2(hour: 15, value: 81),
        HourSPO2(hour: 16, value: 99),
        HourSPO2(hour: 17, value: 79),
        HourSPO2(hour: 18, value: 78),
        HourSPO2(hour: 19, value: 88),
        HourSPO2(hour: 20, value: 76),
        HourSPO2(hour: 21, value: 75),
        HourSPO2(hour: 22, value: 90),
        HourSPO2(hour: 23, value: 96)
    ]
    
    var body: some View {
        SignCardView(type: .pressure, date: date, value: "\(value)\(level)") {
            VStack(spacing: 8) {
                Chart(samples) { item in
                    PointMark(
                        x: .value("Hour", item.hour),
                        y: .value("Pressure", item.value)
                    )
                    .symbol(.circle)
                    .symbolSize(16)
                    .foregroundStyle(Color(hex: "#5B84B8"))
                }
                .frame(height: 40)
                .chartYScale(domain: 70...100)
                .chartYAxis(.hidden)
                .chartXAxis {
                    AxisMarks(values: .stride(by: 1)) { value in
                        AxisGridLine(
                            stroke: StrokeStyle(
                                lineWidth: 0.5
                            )
                        )
                        .foregroundStyle(Color(hex: "#F5F5F5").opacity(0.3))
                    }
                }
                HStack {
                    Text("00:00")
                        .font(.system(size: 12))
                        .foregroundColor(Color(hex: "#B2B2B2"))
                    Spacer()
                    Text("24:00")
                        .font(.system(size: 12))
                        .foregroundColor(Color(hex: "#B2B2B2"))
                }
            }
        }
    }
}

// 定义每日喝水达标数据模型
struct DailyDrink: Identifiable {
    let id = UUID()
    let day: Date
    let completionRate: Int
}

struct DrinkCardView: View {
    let value: String
    let date: String
    
    func generateMonthDrinkData() -> [DailyDrink] {
        var samples: [DailyDrink] = []
        
        let today = Date()
        let calendar = Calendar.current
        
        guard let firstDayOfMonth = calendar.date(from: calendar.dateComponents([.year, .month], from: today)) else {
            return samples
        }
        
        guard let lastDayOfMonth = calendar.date(byAdding: DateComponents(month: 1, day: -1), to: firstDayOfMonth) else {
            return samples
        }
        
        var currentDate = firstDayOfMonth
        while currentDate <= lastDayOfMonth {
            let randomRate = Int.random(in: 40...100)
            
            samples.append(DailyDrink(day: currentDate, completionRate: randomRate))
            
            guard let nextDate = calendar.date(byAdding: .day, value: 1, to: currentDate) else {
                break
            }
            currentDate = nextDate
        }
        
        return samples
    }
    
    var samples: [DailyDrink] {
        generateMonthDrinkData()
    }
    
    private var firstDayOfMonth: String {
        let calendar = Calendar.current
        let today = Date()
        guard let firstDay = calendar.date(from: calendar.dateComponents([.year, .month], from: today)) else {
            return ""
        }
        let formatter = DateFormatter()
        formatter.dateFormat = "d/M"
        return formatter.string(from: firstDay)
    }
    
    private var lastDayOfMonth: String {
        let calendar = Calendar.current
        let today = Date()
        guard let firstDay = calendar.date(from: calendar.dateComponents([.year, .month], from: today)) else {
            return ""
        }
        guard let lastDay = calendar.date(byAdding: DateComponents(month: 1, day: -1), to: firstDay) else {
            return ""
        }
        let formatter = DateFormatter()
        formatter.dateFormat = "d/M"
        return formatter.string(from: lastDay)
    }
    
    var body: some View {
        SignCardView(type: .drinkWaterReminder, date: date, value: value) {
            VStack(spacing: 8) {
                ZStack {
                    Chart(samples) { item in
                        BarMark(
                            x: .value("日期", item.day, unit: .day),
                            y: .value("背景", 100),
                            width: .ratio(0.5)
                        )
                        .foregroundStyle(Color(hex: "#5C5C5C"))
                        .cornerRadius(0)
                    }
                    .frame(height: 50)
                    .chartYScale(domain: 0...100)
                    .chartXAxis(.hidden)
                    .chartYAxis(.hidden)
                    
                    Chart(samples) { item in
                        BarMark(
                            x: .value("日期", item.day, unit: .day),
                            y: .value("达标率", item.completionRate),
                            width: .ratio(0.5)
                        )
                        .foregroundStyle(Color(hex: "#48D9DB"))
                        .cornerRadius(0)
                        
                    }
                    .frame(height: 50)
                    .chartYScale(domain: 0...100)
                    .chartXAxis(.hidden)
                    .chartYAxis(.hidden)
                }
                
                HStack {
                    Text(firstDayOfMonth)
                        .font(.system(size: 12))
                        .foregroundColor(Color(hex: "#B2B2B2"))
                    Spacer()
                    Text(lastDayOfMonth)
                        .font(.system(size: 12))
                        .foregroundColor(Color(hex: "#B2B2B2"))
                }
            }
        }
    }
}

#Preview {
    ScrollView {
        VStack(spacing: 12) {
//            Spo2CardView(date: "4月8日 21:53")
            SleepCardView(quality: "良好", date: "4月8日 22：00-4月9日 05：32")
                .frame(width: 200)
//            WeightCardView(value: "68.5kg", date: "4月9日 07：30")
//            PressureCardView(value: "45", level: "轻度压力", date: "4月9日 10：15")
//            DrinkCardView(value: "93%", date: "4月9日 10：15")
        }
        .padding()
        .background(Color.black)
    }
    
}
